/*
 * Copyright (C) 2015-2016  Nicola Spanti (RyDroid) <dev@nicola-spanti.info>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */


#include "PlanetWars2dRT-core/specific/controller/planet_produce.h"
#include "PlanetWars2dRT-core/specific/model/planet_position.h"
#include "PlanetWars2dRT-core/specific/model/planet_state.h"
#include "PlanetWars2dRT-core/specific/model/planet_observer.h"
#include "PlanetWars2dRT-core/specific/model/planet_observers.h"
#include "PlanetWars2dRT-core/specific/model/ship_default.h"
#include "PlanetWars2dRT-core/specific/model/universe_ships.h"


EXTERN_C_BEGIN


static inline
void
planet_notify_ship_created(planet_t* a_planet, ship_t* a_ship)
{
  struct observer_data_with_code data;
  data.code = PLANET_OBSERVER_CODE_SHIP_CREATED;
  data.data = &a_ship;
  planet_notify_observers(a_planet, &data);
}

static inline
struct ship_t
planet_create_ship_force_no_notify(planet_t* a_planet)
{
  struct ship_t a_ship;
  position_2d_uint position_center = planet_get_center_position(a_planet);
  a_ship = ship_create_default_for_a_player(&position_center,
					    &position_center,
					    a_planet->player_index);
  
  a_planet->nb_updates_before_next_production = a_planet->nb_updates_to_produce;
  
  return a_ship;
}

static inline
struct ship_t
planet_create_ship_force(planet_t* a_planet)
{
  struct ship_t a_ship = planet_create_ship_force_no_notify(a_planet);
  planet_notify_ship_created(a_planet, &a_ship);
  return a_ship;
}

void
planet_produce_force(planet_t* a_planet, universe_t* a_universe)
{
  struct ship_t a_ship = planet_create_ship_force(a_planet);
  
  if(a_universe != NULL)
    {
      universe_add_ship(a_universe, &a_ship);
    }
}

void
planet_produce(planet_t* a_planet, universe_t* a_universe)
{
  if(!planet_is_neutral(a_planet) ||
     (planet_is_neutral(a_planet) && a_planet->produce_when_neutral))
    {
      if(a_planet->nb_updates_before_next_production == 0)
	{
	  planet_produce_force(a_planet, a_universe);
	}
      --a_planet->nb_updates_before_next_production;
    }
}


EXTERN_C_END
